home *** CD-ROM | disk | FTP | other *** search
- /*
- ==========================================================================
- | WINGLEADER |
- | The 3D space combar simulator |
- | |
- | A game of interstellar fighter conflict. |
- | |
- | (c)1989,1990 Chris Roberts. All rights reserved. |
- ==========================================================================
-
- ** NPC PILOT INTELLIGENCE CODE MODULE **
- */
-
- // #define PCI_DEBUG
-
- #define DEBUG_BEGIN if(DEBUG_INFO!=off){select_text_window(&main_screen);
- #define DEBUG_END }
-
- #include <game.h>
-
- extern change_mission_type (int obj, objectives new_obj);
-
- /*-------------------------------------------------------------------------*/
-
- #define DETERMINATION (70-max(0,min(fanatical,pilot_level[obj]))*20)
- /*
- ------------------------------------------------------------------------------
- coming_home()
- ------------------------------------------------------------------------------
- */
-
- #define NEAR_NAV (700)
- #define NEAR_BASE (2000)
-
- void cruise_home(int obj)
- {
- int range;
-
- if( abandoned(obj,your_ship) )
- return;
-
- if ((ship_turn[obj]&7) == 5)
- {
- if (no_goal(obj))
- point_ship_at_point(obj,&destination[obj]);
-
- range = distance_from_point(obj,&destination[obj]);
-
- if (equ_vector(&destination[obj],&ship_mission_spot[obj]))
- {
- if( range<NEAR_BASE )
- {
- reset_tactic(obj,head_home);
-
- set_special(obj,kill_engines);
- zero_vector(&velocity_vec[obj]);
-
- MissionShips[ship_list_index[obj]].Status = SHIP_PARK;
- }
- }
- else
- if( range<NEAR_NAV )
- {
- visit(Flight_path[ship_tmp_index[obj]]);
- get_follow_point(obj,&destination[obj]);
- }
-
- }
-
- }
-
- void fail(int obj)
- {
- report(" => Failure in #%d",obj);
- }
-
- void coming_home (int obj)
- {
- switch( ship_tactic[obj] )
- {
- case cruise: cruise_home(obj); break;
- case head_home:
- if (no_goal(obj))
- point_parallel(obj,find_ship_index(MissionInfo.Carrier));
- break;
- case NONE:
- reset_tactic(obj,cruise);
- get_first_follow_point(obj,&destination[obj]);
- break;
- default: fail(obj);
- }
- }
-
- /*
- ------------------------------------------------------------------------------
- run_away()
- ------------------------------------------------------------------------------
- */
-
- run_away (int obj)
- {
- vec_3D vec;
- #define ROUT_RANGE (16000)
-
- if (isactive(ship_wingleader[obj]))
- if (ship_mission_type[ship_wingleader[obj]] == rout)
- {
- maintain_formation(obj);
- return;
- }
-
- if (side[obj] == Imperial)
- coming_home(obj);
- else
- {
- // All Kilrathi flee straight down.
- zero_vector(&vec);
- vec.y = IntFract(1);
- if (obj&1)
- vec.y = -vec.y;
-
- point_ship(obj,0,&vec);
-
- if( normal_speed(obj) && random(100)<5 )
- fire_afterburner(obj,STD_BURN*2);
- else
- approach_full_speed(obj);
- // This really ought to do some dodging maneuvers during the rout. -KLD
-
- // WARNING: is this remove_object() good enough to kick ship shapes out
- // if necessary?? -RKLD
- if (distance_from_object(obj,your_ship) > ROUT_RANGE)
- remove_object(obj);
- }
-
- }
-
-
- /*
- ------------------------------------------------------------------------------
- */
-
-
- int check_engage_target(int obj) // for combat in general...
- {
- int new_target;
-
- if( (new_target=detect_enemy_tail(obj)) != NONE && new_target!=ship_target[obj] )
- ship_target[obj] = new_target;
- else
- if( !target_valid(obj) )
- select_target(obj);
- return( ship_target[obj] );
- }
-
- int check_destroy_target(int obj)
- {
- int destroy_target = find_ship_index(ship_mission_ship[obj]);
- int test_target;
-
- if( class[destroy_target]==futurion || gone_ship(ship_mission_ship[obj]) )
- check_engage_target(obj);
- else
- if( evaluate_damage(obj)>DETERMINATION )
- {
- ship_target[obj] = destroy_target;
- if( side[destroy_target]==side[obj] )
- warn("KS");
- }
- else
- if( (target_valid(obj) && random(100)>3) )
- check_engage_target(obj);
- else
- ship_target[obj]=destroy_target;
-
- return( ship_target[obj] );
- }
-
- void maneuvering(int obj, int new_target)
- {
- ship_target[obj] = new_target;
-
- intelligence_events(obj);
-
- perform_maneuver(obj);
- }
-
-
-
- /*
- ------------------------------------------------------------------------------
- formation_burst()
- ------------------------------------------------------------------------------
- */
-
- #define BURST_TIMER 9
-
- void formation_burst (int obj)
- {
- vec_3D vec;
- int leader = ship_wingleader[obj];
-
- approach_full_speed(obj);
-
- if (no_goal(obj))
- point_ship(obj,0,&destination[obj]);
-
- if (++ship_count[obj] > BURST_TIMER)
- if( ship_mission_type[obj]==strike )
- engage(obj,ship_target[obj],destroy_ship);
- else
- engage(obj,ship_target[obj],engage_enemy);
- }
-
-
-
- /*
- ------------------------------------------------------------------------------
- capital_combat()
- ------------------------------------------------------------------------------
- */
-
- capital_combat (int obj)
- {
-
- } /* capital_combat() */
-
-
- /*
- ------------------------------------------------------------------------------
- imperial_formation()
- ------------------------------------------------------------------------------
- */
-
- int enemy_sighting = NO_SIGHTINGS;
-
- imperial_formation (int obj)
- {
- int leader = ship_wingleader[obj];
- int target;
- vec_3D dest;
- int closest;
-
- maintain_formation(obj);
-
- #define THREATENING (11000)
- #define VISUAL (14000)
-
- if (attacker_in_range(leader,THREATENING))
- {
- if (auto_engage_timer != NONE)
- if (--auto_engage_timer == 0)
- allow_engage();
-
- if( allowed_to_engage(obj) ) // target ship is pulled out of the blue! -RKLD
- engage(obj,target_ship,engage_enemy);
- else
- if (obj == your_wingman)
- if (
- (ship_turn[obj]&15)==0 &&
- (auto_engage_timer == NONE)
- )
- {
- send_message(obj, COM_atk_request);
- auto_engage_timer = 25;
- }
- }
- else
- {
- if( obj==your_wingman && enemy_sighting!=current_wave && any_enemy(obj,VISUAL) )
- if( !message_showing() && cockpit_view==front )
- {
- send_message(obj,COM_i_see_enemy);
- enemy_sighting = current_wave;
- }
- }
-
- #define FAR_AWAY (9000)
- #define TOWARD (85)
-
- if (special_maneuver[obj] == NONE)
- if (distance_from_object(obj,leader) > FAR_AWAY)
- if ((facing_to_object(obj,leader) > TOWARD)
- && (real_velocity(obj) < 110 ))
- fire_afterburner(obj,STD_BURN);
- else
- {
- point_ship_at_object(obj,leader);
- approach_ship_speed(obj,leader);
- }
-
- } /* imperial_formation() */
-
-
- /*
- ------------------------------------------------------------------------------
- formation_break()
- ------------------------------------------------------------------------------
- */
-
- formation_break (int obj)
- {
-
- /*
- WHENEVER SOMEBODY DESIGNS THE FORMATIONS SOME SCRIPTS
- WILL HAVE TO BE SET UP FOR THE WINGMEN TO BREAK AWAY
- FROM THE FORMATION IN A VISUALLY EXCITING MANNER...
- */
-
- switch (ship_seq[obj])
- {
- case 0:
- steady_object(obj);
- yaw_goal[obj] = -30;
- roll_goal[obj] = -45;
- pitch_goal[obj] = -20;
- ++ship_seq[obj];
- break;
-
- case 1:
- if (no_goal(obj))
- engage(obj,ship_target[obj],engage_enemy);
- break;
- default: ship_seq[obj] = 0;
- }
- }
-
-
-
- /*
- ------------------------------------------------------------------------------
- imperial_wingman()
- routine for a WINGMAN on the Player's Side on a PATROL mission
- ------------------------------------------------------------------------------
- */
-
- void imperial_wingman (int obj)
- {
- int target;
- int leader = ship_wingleader[obj];
-
- switch (ship_objective[obj])
- {
- case hold_formation: imperial_formation(obj); break;
- case break_formation: formation_break(obj); break;
- case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
- case destroy_ship: maneuvering(obj,check_destroy_target(obj)); break;
- case NONE: reset_objective(obj,hold_formation); break;
- default: fail(obj);
- }
- }
-
-
- /*
- ------------------------------------------------------------------------------
- kilrathi_wingman()
- ------------------------------------------------------------------------------
- */
-
- void kilrathi_wingman(int obj)
- {
- int leader = ship_wingleader[obj];
-
- if (leader == NONE)
- {
- change_mission_type(obj,patrol);
- return;
- }
- else
- if( unactive(leader) )
- {
- inherit_leader(obj);
- return;
- }
-
- if( ship_objective[leader]==engage_enemy || ship_objective[leader]==destroy_ship )
- if( ship_objective[obj]!=ship_objective[leader] )
- engage(obj,ship_target[obj],ship_objective[leader]);
-
- switch( ship_objective[obj] )
- {
- case hold_formation: maintain_formation(obj); break;
- case break_formation: formation_burst(obj); break;
- case destroy_ship: // protect your wingleader!
- case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
- case NONE: reset_objective(obj,hold_formation); break;
- default: fail(obj);
- }
-
- }
-
-
- /*
- ------------------------------------------------------------------------------
- wingman_mission()
- ------------------------------------------------------------------------------
- */
-
- void wingman_mission(int obj)
- {
- if( side[obj]==Imperial )
- imperial_wingman(obj);
- else
- kilrathi_wingman(obj);
- }
-
- /*
- ------------------------------------------------------------------------------
- */
-
- int dist_from_home(int obj)
- {
- return( distance_from_point(obj,&ship_mission_spot[obj]) );
- }
-
- /*
- ------------------------------------------------------------------------------
- kilrathi_patrol()
- ------------------------------------------------------------------------------
- */
- #define PATROL_RADIUS (8000) // when this far out, must get closer.
- #define WANDER_RADIUS (3000) // when this close to patrol pt, can wander.
- #define APPROACH_BEHIND (490)
- #define NORMAL_SCANNER (14000)
- #define APPROACH_RANGE (10000) // break form now.
-
- int scan_and_lock(int obj, int scan_range, tactics new_tactic)
- {
- int new_target;
-
- ship_target[obj] = scan_for_enemy(obj,NORMAL_SCANNER);
- if( ship_target[obj]!=NONE )
- ship_tactic[obj] = new_tactic;
- return( ship_target[obj]!=NONE );
- }
-
- void patrol_area(int obj)
- {
- int target = ship_target[obj];
- unsigned int range;
- vec_3D spot;
-
- switch (ship_tactic[obj])
- {
- case look_out:
- approach_cruise_speed(obj);
- if( !scan_and_lock(obj,NORMAL_SCANNER,approach_target) )
- if( dist_from_home(obj) > PATROL_RADIUS )
- reset_tactic(obj,head_home);
- break;
-
- case head_home:
- approach_cruise_speed(obj);
- if( !scan_and_lock(obj,NORMAL_SCANNER,approach_target) )
- {
- ship_vs_point(obj,&ship_mission_spot[obj]);
-
- if( target_range<WANDER_RADIUS )
- reset_tactic(obj,look_out);
- else
- {
- // what exactly does this do? -KLD
- point_ship_at_point(obj,&ship_mission_spot[obj]);
- trim_goals(obj,7);
- }
- }
- break;
-
- case approach_target:
- approach_full_speed(obj);
- if( unactive(target) )
- {
- if( !scan_and_lock(obj,NORMAL_SCANNER,approach_target) )
- alter_tactic(obj,look_out);
- }
- else
- {
- ship_vs_ship(obj,target);
-
- if( target_range<APPROACH_RANGE )
- init_formation_burst(obj);
- else
- if( no_goal(obj) )
- point_ship_at_object(obj,target);
- }
- break;
-
- case NONE: reset_tactic(obj,approach_target); break;
- default: fail(obj);
- }
- }
-
-
-
- void kilrathi_patrol (int obj)
- {
- switch( ship_objective[obj] )
- {
- case break_formation: formation_burst(obj); break;
- case hold_formation:
- case wander: patrol_area(obj); break;
- case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
- case NONE:
- ship_objective[obj] = wander;
- ship_tactic[obj] = approach_target;
- break;
- default: fail(obj);
- }
- }
-
-
- /*
- ------------------------------------------------------------------------------
- imperial_wingleader()
- ------------------------------------------------------------------------------
- */
-
- imperial_wingleader (int obj)
- {
- kilrathi_patrol(obj); // there is no specialized Impeial leader
- // intelligence yet... it may not be needed?
- } /* imperial_wingleader() */
-
-
- /*
- ------------------------------------------------------------------------------
- reach_warp()
- ------------------------------------------------------------------------------
- */
-
- #define TOWARD (65)
- void cruise_to_destination(int obj)
- {
- int range;
-
- // Don't move if you're too far away:
- if( abandoned(obj,your_ship) ) return;
-
- // Set speed according to presence of enemies:
- if( (ship_turn[obj]&7)==6 )
- ship_target[obj] = scan_for_enemy(obj,CAPITAL_SCANNER_RANGE);
-
- if (ship_target[obj] == NONE)
- approach_cruise_speed(obj);
- else
- {
- get_facing_range_from_object(obj,ship_target[obj]);
-
- if (facing_to_target > TOWARD)
- approach_half_speed(obj); // slow when approaching enemies.
- else
- approach_full_speed(obj); // accelerate out from them.
- }
-
- // Check destination:
- if ((ship_turn[obj]&7) == 2)
- {
- if (no_goal(obj))
- point_ship_at_point(obj,&destination[obj]);
-
- range = distance_from_point(obj,&destination[obj]);
-
- if( range < NEAR_NAV )
- {
- flag_reached(Flight_path[ship_tmp_index[obj]]);
- if (equ_vector(&destination[obj],&ship_mission_spot[obj]))
- {
- reset_tactic(obj,sit_still);
- set_special(obj,kill_engines);
- }
- else
- get_follow_point(obj,&destination[obj]);
- }
- }
- }
-
- #define WARP_OUT_RANGE (4000)
- #define PREPARE_WARP_TIMER 10
- void prepare_for_jump(int obj)
- {
- if( speed[obj]!=0 )
- set_special(obj,stop_drift);
- else
- if (object_nearby(obj,your_ship,WARP_OUT_RANGE))
- if (++ship_count[obj] > PREPARE_WARP_TIMER)
- {
- reset_tactic(obj,warp_out);
- fire_afterburner(obj,STD_BURN);
- }
- }
-
- #define ACCELERATION_TIMER 3
- void accelerate_and_jump(int obj)
- {
- approach_full_speed(obj);
-
- if (ship_count[obj]++ == ACCELERATION_TIMER)
- warp(obj);
- }
-
- /////////////////////////////////////////////////////
- void reach_warp (int obj)
- {
- switch (ship_tactic[obj])
- {
- case cruise: cruise_to_destination(obj); break;
- case sit_still: prepare_for_jump(obj); break;
- case warp_out: accelerate_and_jump(obj); break;
- case NONE:
- reset_tactic(obj,cruise);
- get_first_follow_point(obj,&destination[obj]);
- break;
- default: fail(obj);
- }
- }
-
-
- /*
- ------------------------------------------------------------------------------
- warp_arrival()
- ------------------------------------------------------------------------------
- */
-
- void arrive_from_warp(int obj)
- {
- int index = find_objective(nav_point,Current_action_sphere);
-
- if (index != NONE) // Don't really need to go to that Nav Point...
- {
- visit(index);
- if (Current_Objective == index)
- set_next_destination();
- }
-
- unwarp(obj);
- speed[obj] = IntToIntFract(data[type[obj]].max_velocity);
- fix_velocity(obj);
-
- reset_mission_type(obj,patrol);
- }
-
-
- void warp_arrival(int obj)
- {
- if( ship_tactic[obj]==warp_in )
- arrive_from_warp(obj);
- else
- reset_tactic(obj,warp_in);
- }
-
-
- /*
- ------------------------------------------------------------------------------
- escort_mission()
- ------------------------------------------------------------------------------
- */
- #define ESCORT_RESUMED (1000)
-
- void return_to_buddy(int obj, int buddy)
- {
- approach_cruise_speed(obj);
- if( no_goal(obj) )
- point_ship_at_object(obj,buddy);
- if( distance_from_object(obj,buddy)<ESCORT_RESUMED )
- {
- reset_objective(obj,wander);
- point_parallel(obj,buddy);
- }
- }
-
- void escort_buddy(int obj, int buddy)
- {
- approach_ship_speed(obj,buddy);
- if (no_goal(obj))
- point_parallel(obj,buddy);
- }
-
- #define ESCORT_DANGER (3000)
- #define ESCORT_DRIFT (5000) // This should be more than ESCORT_DANGER
- #define ESCORT_RADIUS (1200)
-
- void escort_mission(int obj)
- {
- int buddy = find_ship_index(ship_mission_ship[obj]);
-
- if (unactive(buddy))
- {
- change_mission_type(obj,patrol);
- return;
- }
-
- if( !(ship_turn[obj]&3) )
- if( in_danger(buddy) )
- if( target_range < ESCORT_DANGER )
- engage(obj,target_ship,engage_enemy);
-
- if (ship_objective[obj] != home_base)
- if( (ship_turn[obj]&7)==4 )
- if (distance_from_object(obj,buddy) > ESCORT_DRIFT)
- reset_objective(obj,home_base);
-
- switch( ship_objective[obj] )
- {
- case wander: escort_buddy(obj,buddy); break;
- case home_base: return_to_buddy(obj,buddy); break;
- case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
- case NONE: reset_objective(obj,wander); break;
- default: fail(obj);
- }
-
- }
-
-
- /*
- ------------------------------------------------------------------------------
- strike_mission()
- ------------------------------------------------------------------------------
- */
-
- void check_goal(int obj)
- {
- vec_3D xyz;
- if( gone_ship(ship_mission_ship[obj]) )
- reset_mission_type(obj,rout);
- else
- {
- warn("This shouldn't happen!",0);
- locate_ship(ship_mission_ship[obj],&xyz);
- if (no_goal(obj))
- point_ship_at_point(obj,&xyz);
- approach_full_speed(obj);
- }
- }
-
- void streak_toward(int obj, int goal, int range)
- {
- if( no_goal(obj) )
- if( random(100)<95 )
- point_ship_at_object(obj,goal);
- else
- veer_random(obj,20);
-
- if( range>2000 && normal_speed(obj) )
- fire_afterburner(obj,STD_BURN);
- else
- approach_full_speed(obj);
- }
-
-
-
- #define ENGAGE_RANGE (5000) // just a bit shorter than normal...
- void approach_and_engage(int obj, int goal)
- {
- unsigned int range, possible_range;
- int possible_target;
-
- range = distance_from_object(obj,goal);
- if( class[goal]!=futurion && evaluate_damage(obj)>DETERMINATION && range>ENGAGE_RANGE )
- streak_toward(obj,goal,range);
- else
- {
- possible_target = scan_for_enemy(obj,10000);
- possible_range = target_range;
- if( possible_target!=NONE && (possible_range*3<range || class[goal]==futurion) )
- {
- init_formation_burst(obj);
- ship_target[obj] = possible_target;
- }
- else
- if( range<ENGAGE_RANGE )
- engage(obj,goal,destroy_ship);
- else
- streak_toward(obj,goal,range);
- }
- }
-
- void strike_mission (int obj)
- {
- int goal = find_ship_index(ship_mission_ship[obj]);
-
- // Check status of STRIKE objective ship...
- if( goal==NONE && class[goal]!=futurion )
- check_goal(obj);
-
- switch( ship_objective[obj] ) {
- case break_formation: formation_burst(obj); break;
- case hold_formation:
- case home_base: approach_and_engage(obj,goal); break;
- case engage_enemy: maneuvering(obj,check_destroy_target(obj)); break;
- case destroy_ship: maneuvering(obj,check_destroy_target(obj)); break;
- case NONE:reset_objective(obj,home_base); break;
- default: fail(obj);
- }
- }
-
-
- /*
- ------------------------------------------------------------------------------
- defend_mission()
- ------------------------------------------------------------------------------
- */
- #define DEFEND_RADIUS (6000)
- #define DEFEND_RESUMED (5000) // must be less than the defend radius.
-
- void return_to_master(int obj, int master)
- {
- int range = distance_from_object(obj,master);
-
- streak_toward(obj,master,range);
-
- if( range<DEFEND_RESUMED )
- {
- reset_objective(obj,wander);
- point_perpendicular(obj,master);
- }
- }
-
-
- void defend_mission (int obj)
- {
- int master = find_ship_index(ship_mission_ship[obj]);
-
- if( master==NONE )
- {
- change_mission_type(obj,patrol);
- return;
- }
-
- if( ship_turn[obj]%10 == 0 )
- if( in_danger(master) )
- if( target_range<DEFEND_RADIUS )
- {
- if( ship_objective[obj]!=engage_enemy)
- engage(obj,target_ship,engage_enemy);
- }
-
- if( ship_objective[obj]!=home_base )
- if ((ship_turn[obj]&7) == 4)
- if (distance_from_object(obj,master) > 10000)
- reset_objective(obj,home_base);
-
- switch( ship_objective[obj] )
- {
- case wander:
- ship_target[obj] = scan_for_enemy(obj,7000);
- if( ship_target[obj]!=NONE )
- engage(obj,ship_target[obj],engage_enemy);
- else
- {
- approach_half_speed(obj);
- if (no_goal(obj))
- point_perpendicular(obj,master);
- }
- break;
- case home_base: return_to_master(obj,master); break;
- case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
- case NONE: reset_objective(obj,wander); break;
- default: fail(obj);
- }
- }
-
-
- /*
- ------------------------------------------------------------------------------
- rendezvous_mission()
-
- RENDEZVOUS missions are for Ships travelling to another Ship, usually
- a Capital Ship, that it will be set to DEFEND as a new mission type...
- ------------------------------------------------------------------------------
- */
-
- rendezvous_mission (int obj)
- {
- int goal = find_ship_index(ship_mission_ship[obj]);
-
- if (unactive(goal))
- {
- change_mission_type(obj,patrol);
- return;
- }
-
- switch (ship_objective[obj])
- {
- case (reach_ship):
- if (attacker_in_range(obj,3500)) // only very close attackers
- engage(obj,target_ship,engage_enemy);
-
- if (IS_NEAR(obj,goal,2500))
- {
- reset_mission_type(obj,defend);
- return;
- }
-
- if (attacker_in_range(goal,9000))
- approach_full_speed(obj);
- else
- approach_cruise_speed(obj);
-
- if (no_goal(obj))
- point_ship_at_object(obj,goal);
- break;
-
- case (engage_enemy): maneuvering(obj,check_engage_target(obj)); break;
-
- default: reset_objective(obj,reach_ship);
- }
-
-
- } /* rendezvous_mission() */
-
-
- /*
- ------------------------------------------------------------------------------
- ship_intelligence()
- ------------------------------------------------------------------------------
- */
-
- void ship_intelligence (int obj)
- {
- int target;
-
- if( regulate_turn(obj) ) return;
-
- switch (ship_mission_type[obj])
- {
- case (patrol):
- if( side==Imperial )
- imperial_wingleader(obj);
- else
- kilrathi_patrol(obj);
- break;
-
- case (escort): escort_mission(obj); break;
-
- case (strike): strike_mission(obj); break;
-
- case (defend): defend_mission(obj); break;
-
- case (wingman): wingman_mission(obj); break;
-
- case (rendezvous): rendezvous_mission(obj); break;
-
- case (rout): run_away(obj); break;
-
- case NONE: inherit_leader_mission(obj); break;
-
- default: fail(obj);
- }
-
- }
-
-
- /*
- ------------------------------------------------------------------------------
- capital_ship_intelligence()
- ------------------------------------------------------------------------------
- */
-
- void mega_ship (int obj) // only used for the ralari. -KLD
- {
- int radius = MissionSpheres[Current_action_sphere].Radius>>1;
- vec_3D center = MissionSpheres[Current_action_sphere].Center;
- int range;
-
- if (fire_turrets(obj))
- {
- ship_target[obj] = NONE;
- approach_half_speed(obj);
- }
- else
- approach_cruise_speed(obj);
-
- range = distance_from_point(obj,¢er);
-
- if (no_goal(obj))
- if (range > radius-750)
- if (range > radius)
- point_ship_at_point(obj,¢er);
- else
- point_perpendicular_to_point(obj,¢er);
-
- trim_goals(obj,5);
-
- } /* mega_ship() */
-
-
- void capital_ship_intelligence (int obj)
- {
- if (regulate_turn(obj))
- return;
-
- switch (ship_mission_type[obj])
- {
- case goto_warp: reach_warp(obj); break;
-
- case warp_arrive: warp_arrival(obj); break;
-
- case come_home: coming_home(obj); break;
-
- case rout: run_away(obj); break;
-
- case patrol: // well...? -KLD
-
- default :
-
- if (
- type[obj] == Ralari ||
- type[obj] == Fralthi
- )
- {
- mega_ship(obj); // just testing for now... (pci)
- return;
- }
-
- if (unactive( target_ship = ship_target[obj] ))
- scan_for_enemy(obj,CAPITAL_SCANNER_RANGE);
-
- switch (ship_tactic[obj])
- {
- case (self_defense):
- approach_full_speed(obj);
- if( unactive(ship_target[obj]) )
- {
- select_target(obj);
- if( unactive(ship_target[obj]) )
- reset_tactic(obj,NONE); // seems reasonable, but... -KLD
- }
- else
- fire_turrets(obj);
- break;
-
- default :
- // How would target_ship ever be set to anything here? -KLD
- if (target_ship != NONE)
- {
- approach_full_speed(obj);
- ship_tactic[obj] = self_defense;
- ship_target[obj] = target_ship;
- fire_turrets(obj);
- }
- else // follow Bee Line in
- approach_cruise_speed(obj); // ship's current dir
- }
-
- }
-
- }
-
- /*
- ------------------------------------------------------------------------------
- futurion_intelligence()
-
- this routine holds off an object from taking on its true
- class until your_ship is nearby and looking toward it...
- the proper class should be stored in object_counter[un_obj]
- ------------------------------------------------------------------------------
- */
-
- futurion_intelligence (int un_obj)
- {
- #define MUST_ARRIVE 49
-
- ship_vs_ship(your_ship,un_obj); // Velveteen Rabbit...
-
- if (
- (++action_count[un_obj] > MUST_ARRIVE) ||
- (target_range < 7000) && (facing_to_target > 80)
- )
- if (one_in(8))
- class[un_obj] = object_counter[un_obj]; // become a REAL class
-
- } /* futurion_intelligence() */
-
-
-
- /*
- ------------------------------------------------------------------------------
- mine_intelligence()
- ------------------------------------------------------------------------------
- */
-
- void mine_intelligence (int obj)
- {
- int target_ship;
- int distance;
-
- if (object_counter[obj] != 0) /* can't explode until active! */
- return;
-
- /*-- Check to see if any ships are in the vincinity of the mine --*/
- for (target_ship = your_ship; target_ship <= last_ship; target_ship++)
- {
- if (obj != target_ship)
- {
- if (class[target_ship] == ship)
- {
- if (distance_from_object(obj, target_ship) < MINE_DETONATION_RANGE)
- {
- /*-- If ship is too close to mine, it explodes --*/
- explode(obj);
- return;
- }
- }
- }
- }
- } /* mine_intelligence() */
-
-
- /*
- ------------------------------------------------------------------------------
- heat_seeking_missile_intelligence()
- ------------------------------------------------------------------------------
- */
-
- void heat_seeking_missile_intelligence (int obj)
- {
- int exhaust_heat, target_ship, targ;
-
- /*--------Intelligence used for heat seeking missiles ---------*/
-
- // This is implemented wrong. Heat seekers need enemy to be facing away... -KLD
- if (facing_to_target < 0 || ship_target[obj] == NONE)
- {
- /*-- If lock is lost on the target, look for closest "hotest" target --*/
- ship_target[obj] = NONE;
-
- viable_target_index = 0;
- for (target_ship = your_ship; target_ship <= last_ship; target_ship++)
- {
- if( obj!=target_ship && class[target_ship]==ship )
- {
- get_facing_range_from_object(obj, target_ship);
- if( target_range<MISSILE_SCAN_RANGE && facing_to_target>0 && target_facing<0 )
- {
- /*-- If ship's engines are in missile's lock arc --*/
- viable_target[viable_target_index] = target_ship;
- viable_target_dist[viable_target_index++] = target_range;
- }
- }
- }
- sort_viable_target_list();
- if (viable_target_index >0)
- {
- for (exhaust_heat = hot; exhaust_heat > cold; exhaust_heat--)
- {
- for (targ=0;targ<viable_target_index;targ++)
- {
- if (exhaust_hot[viable_target[targ]] == exhaust_heat)
- {
- /*-- Found a new target to lock onto --*/
- ship_target[obj] = viable_target[targ];
- exhaust_heat = cold;
- break;
- }
- }
- }
- }
- if (ship_target[obj] == NONE)
- explode(obj);
- }
- else
- {
- point_ship(obj, 0, &to_target);
- speed[obj] = IntToIntFract(data[type[obj]].max_velocity+10);
- }
- } /* heat_seeking_missile_intelligence() */
-
-
- /*
- ------------------------------------------------------------------------------
- FF_missile_intelligence()
- ------------------------------------------------------------------------------
- */
-
- void FF_missile_intelligence (int obj)
- {
- int target_ship;
-
- if (ship_tactic[obj] == ram)
- {
- /*-- Missile is set to ram, after rockets have been ignited --*/
- if (ship_target[obj] == NONE)
- {
- /*-- Aquire a target for missile --*/
-
- /*-- Find the closest foe for the FF_missile to lock onto --*/
- viable_target_index = 0;
- for (target_ship = your_ship; target_ship <= last_ship; target_ship++)
- {
- if (obj != target_ship)
- {
- if (class[target_ship] == ship)
- {
- if (side[target_ship] != side[parent[obj]] || communicator[target_ship] == BAD)
- {
- target_range = distance_from_object(obj, target_ship);
- if (target_range < MISSILE_SCAN_RANGE)
- {
- /*-- If ship is close enough for missile to lock onto --*/
- viable_target[viable_target_index] = target_ship;
- viable_target_dist[viable_target_index++] = target_range;
- }
- }
- }
- }
- }
- sort_viable_target_list();
- if (viable_target_index >0)
- {
- /*-- lock onto closest possible target --*/
- ship_target[obj] = viable_target[0];
- }
- /* If to target aquired, repeat process next turn, until missile
- self destructs */
- }
- else
- {
- point_ship(obj, 0, &to_target);
- speed[obj] = IntToIntFract(data[type[obj]].max_velocity+10);
- }
- }
- } /* FF_missile_intelligence() */
-
-
-
- /* ------------------------ */
-
-
- // PAUL! what is this garbage!!! -RKLD (pci) Testing capital ship firing
- x ()
- {
- int it;
-
- for (it=0; it<=ships; it++)
- if (type[it] == Tigers_claw)
- {
- reset_mission_type(it,patrol);
- ship_target[it] = your_ship;
- side[it] = Kilrathi;
- }
-
- } /* x() */